package com.abe.libcore.base.screen

import android.annotation.SuppressLint
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import android.widget.TextView
import java.lang.reflect.Field


/**
 * 重新布局工具类, 迭代的形式将视图层级按比例缩放
 */
@SuppressWarnings("unchecked")
object RelayoutTool {
    /**
     * 原视图 宽高、padding、margin、 及文本字体大小 按比例缩放，重新布局；
     *
     * @param view  单个视图，或视图层级
     * @param scale 缩放比例
     */
    @SuppressLint("SoonBlockedPrivateApi")
    fun relayoutViewHierarchy(view: View?, scale: Float) {
        if (view == null) {
            return
        }
        scaleView(view, scale)
        if (view is ViewGroup) {
            var children: Array<View>? = null
            try {
                val field = ViewGroup::class.java.getDeclaredField("mChildren") as Field
                field.isAccessible = true
                children = field.get(view) as Array<View>
            } catch (e: NoSuchFieldException) {
                e.printStackTrace()
            } catch (e: IllegalArgumentException) {
                e.printStackTrace()
            } catch (e: IllegalAccessException) {
                e.printStackTrace()
            }
            if (children != null) {
                for (child in children) {
                    relayoutViewHierarchy(child, scale)
                }
            }
        }
    }

    /**
     * 将视图按比例缩放，不考虑嵌套视图；
     *
     * @param view  不考虑嵌套，缩放单个View；
     * @param scale 缩放比例；
     */
    private fun scaleView(view: View, scale: Float) {
        if (view is TextView) {
            resetTextSize(view, scale)
        }
        val pLeft = convertFloatToInt(view.paddingLeft * scale)
        val pTop = convertFloatToInt(view.paddingTop * scale)
        val pRight = convertFloatToInt(view.paddingRight * scale)
        val pBottom = convertFloatToInt(view.paddingBottom * scale)
        view.setPadding(pLeft, pTop, pRight, pBottom)
        val params = view.layoutParams
        scaleLayoutParams(params, scale)
    }

    /**
     * 将视图布局属性按比例设置；
     *
     * @param params params
     * @param scale  缩放比例；
     */
    fun scaleLayoutParams(params: ViewGroup.LayoutParams?, scale: Float) {
        if (params == null) {
            return
        }
        if (params.width > 0) {
            params.width = convertFloatToInt(params.width * scale)
        }
        if (params.height > 0) {
            params.height = convertFloatToInt(params.height * scale)
        }
        if (params is MarginLayoutParams) {
            val mParams = params as MarginLayoutParams?
            if (mParams!!.leftMargin > 0) {
                mParams.leftMargin = convertFloatToInt(mParams.leftMargin * scale)
            }
            if (mParams.rightMargin > 0) {
                mParams.rightMargin = convertFloatToInt(mParams.rightMargin * scale)
            }
            if (mParams.topMargin > 0) {
                mParams.topMargin = convertFloatToInt(mParams.topMargin * scale)
            }
            if (mParams.bottomMargin > 0) {
                mParams.bottomMargin = convertFloatToInt(mParams.bottomMargin * scale)
            }
        }
    }

    /**
     * 将 TextView（或其子类）文本大小按比例缩放；
     *
     * @param textView textView
     * @param scale    缩放比例；
     */
    private fun resetTextSize(textView: TextView, scale: Float) {
        val size = textView.textSize
        textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, size * scale)
    }

    /**
     * float 转换至 int 小数四舍五入
     */
    private fun convertFloatToInt(sourceNum: Float): Int {
        return (sourceNum + 0.5f).toInt()
    }
}